Add position filter for radius, courtesy Alex Mottram.
authorrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Mon, 28 Apr 2003 13:45:04 +0000 (13:45 +0000)
committerrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Mon, 28 Apr 2003 13:45:04 +0000 (13:45 +0000)
gpsbabel/README
gpsbabel/filter_vecs.c
gpsbabel/position.c
gpsbabel/testo

index 0db94a67977927cc19cbf3a7ff96b47403ebd9fc..a5e64c4a12f142bc171a065e5bffae1aeb626a83 100644 (file)
@@ -336,6 +336,23 @@ DATA FILTERS
        leaving just one.
 
 
+    RADIUS
+
+       The radius filter is designed to include points based on their
+       proximity to a central point.  Distances and the central point 
+       are declared on the command line by passing the distance=X.XX,
+       lat=X.XX, and lon=X.XX options to the filter.  Distance options 
+       may be expressed in miles (distance=3M) or kilometers (distance=3K).
+       The default is zero miles.
+
+       For example:
+
+       gpsbabel -i geo -f 1.loc -x radius,distance=1.5M,lat=30.0,lon=-90.0 \
+                -o mapsend -F 2.wpt
+
+       would include only points within 1.5 miles of N30.000 W90.000 
+
+
     DUPLICATE
 
        The duplicate filter is designed to remove duplicate points based
index 4dc76b0de0c3a97fc20b8c90781c1f623f20af0f..3f87a8700ae0a7e14c91a4cf5831eca983b7ea4a 100644 (file)
@@ -29,6 +29,7 @@ typedef struct {
 } fl_vecs_t;
 
 extern filter_vecs_t position_vecs;
+extern filter_vecs_t radius_vecs;
 extern filter_vecs_t duplicate_vecs;
 
 static
@@ -38,6 +39,11 @@ fl_vecs_t filter_vec_list[] = {
                "position",
                "Remove Points Within Distance",
        }, 
+       {
+               &radius_vecs, 
+               "radius",
+               "Include Only Points Within Radius",
+       }, 
        {
                &duplicate_vecs, 
                "duplicate",
index 36cceb54f0dcea1eca3b61d50a1ab4571c4992ba..3c1b7a01978300ab9802269e5ed993349ab484e2 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Distance Between Points Filter
+    Distance Between Points Filter(s)
 
     Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
 
@@ -30,6 +30,10 @@ extern queue waypt_head;
 
 static double pos_dist;
 static char *distopt;
+static char *latopt;
+static char *lonopt;
+
+waypoint * home_pos;
 
 static
 arglist_t position_args[] = {
@@ -37,6 +41,14 @@ arglist_t position_args[] = {
        {0, 0, 0}
 };
 
+static
+arglist_t radius_args[] = {
+       {"lat", &latopt,       "Latitude for center point (D.DDDDD)"},
+       {"lon", &lonopt,       "Longitude for center point (D.DDDDD)"},
+       {"distance", &distopt, "Maximum distance from center"},
+       {0, 0, 0}
+};
+
 static double
 gc_distance(double lat1, double lon1, double lat2, double lon2)
 {
@@ -81,7 +93,7 @@ position_comp(const void * a, const void * b)
        return(0);
 }
 
-void
+void 
 position_process(void)
 {
        queue * elem, * tmp;
@@ -111,7 +123,7 @@ position_process(void)
                /* convert radians to integer feet */
                dist = (int)((((dist * 180.0 * 60.0) / M_PI) * 1.1516) * 5280.0);
 
-               if (dist <= pos_dist) { 
+               if (dist <= pos_dist) {
                        waypt_del(comp[i]);
                        waypt_free(comp[i]);
                }
@@ -141,9 +153,70 @@ void
 position_deinit(void) {
 }
 
+void 
+radius_process(void)
+{
+       queue * elem, * tmp;
+       waypoint * waypointp;
+       double dist;
+
+       QUEUE_FOR_EACH(&waypt_head, elem, tmp) {
+               waypointp = (waypoint *)elem;
+
+               dist = gc_distance(waypointp->position.latitude.degrees,
+                                  waypointp->position.longitude.degrees,
+                                  home_pos->position.latitude.degrees,
+                                  home_pos->position.longitude.degrees);
+
+               /* convert radians to float point statute miles */
+               dist = (((dist * 180.0 * 60.0) / M_PI) * 1.1516);
+
+               if (dist >= pos_dist) {
+                       waypt_del(waypointp);
+                       waypt_free(waypointp);
+               }
+       }
+}
+
+void
+radius_init(const char *args) {
+       char *fm;
+
+       pos_dist = 0;
+
+       if (distopt) {
+               pos_dist = strtod(distopt, &fm);
+
+               if ((*fm == 'k') || (*fm == 'K')) {
+                        /* distance is kilometers, convert to feet */
+                       pos_dist *= .6214;
+               }
+       }
+
+       home_pos = xcalloc(sizeof(*home_pos), 1);
+
+       if (latopt)
+               home_pos->position.latitude.degrees = atof(latopt);
+       if (lonopt)
+               home_pos->position.longitude.degrees = atof(lonopt);
+}
+
+void
+radius_deinit(void) {
+       if (home_pos)
+               xfree(home_pos);
+}
+
 filter_vecs_t position_vecs = {
        position_init,
        position_process,
        position_deinit,
        position_args
 };
+
+filter_vecs_t radius_vecs = {
+       radius_init,
+       radius_process,
+       radius_deinit,
+       radius_args
+};
index 2ff9ba6433b004c46454c0352e730aaf863f8778..4c218bb8facfdf85fd96a650f88295325ad13c57 100755 (executable)
@@ -239,6 +239,15 @@ ${PNAME} -i geo -f geocaching.loc -f geocaching.loc -x position,distance=5f \
                -o csv -F ${TMPDIR}/filterpos.csv2
 compare ${TMPDIR}/filterpos.csv1 ${TMPDIR}/filterpos.csv2
 
+#
+# Radius filter
+#
+rm -f ${TMPDIR}/radius.csv
+${PNAME} -i geo -f geocaching.loc \
+               -x radius,lat=35.9720,lon=-87.1347,distance=14.7 \
+               -o csv -F ${TMPDIR}/radius.csv
+compare ${TMPDIR}/radius.csv reference/
+
 #
 # magellan SD card waypoint / route format
 #